import Darwin

enum Token {
    case number(Int)
    case plus
}

class lexer {
    
    //内部错误枚举
    enum Error:Swift.Error {
        case invalidCharacter(Character)
    }
    
    let input:String.CharacterView
    var position:String.CharacterView.Index
    
    init(input:String){
        self.input = input.characters
        self.position = self.input.startIndex
    }
    
    func peek() -> Character? {
        guard position < input.endIndex else {
            return nil
        }
        return input[position]
    }
    
    func advance() {
        //断言
        //第一个参数是必须满足的条件,如果为true,什么都不会发生
        //如果为false,就会崩溃
        //assert断言只在调试模式下生效,在发布模式中会被自动删除
        //如果想在发布模式中保留断言功能,可以使用precondition(_:_:),功能和assert是一样的
        assert(position < input.endIndex,"Cannot advance past endIndex")
        position = input.index(after: position)
    }
    
    func lex() throws -> [token] {
        var tokens = [token]()
        
        while let nextCharacter = peek(){
            switch nextCharacter {
            case "0" ... "9":
                //开始处理数,需要获取数的剩余部分
                let value = getNumber()
                tokens.append(.number(value))!
            case "+":
                tokens.append(.plus)
                advance()
                
            case " ":
                //前进,忽略空格
                advance()
            default:
                //出乎意料---需要返回错误
                throw Lexer.Error.invalidCharacter(nextCharacter)
            }
        }
    }
    
    func getNumber() -> Int {
        var value = 0
        
        while let nextCharacter = peek() {
            switch nextCharacter {
            case "0" ... "9":
                //还有数字,加到结果上
                let digitValue = Int(String(nextCharacter))
                value = 10*value + digitValue
                advance()
            default:
                //非数字,回到常规的语法分析
                return value
            }
        }
        return value
    }
}
